/**
 * tigerrad
 * fall 2006
 */

#ifndef _RENDERTARGET_H
#define _RENDERTARGET_H

#include "Util.h"
#include "Texture.h"
#include "Renderbuffer.h"

/**
 * Abstracts a Render Target.  Creates and manages the framebuffer object and texture(s).
 */
class RenderTarget
{
	public:
		/**
		 * Constructor.
		 * @param name Debug name(id)
		 * @param size Size of the render target
		 */
		RenderTarget(const std::string& name, const Vec2s& size) :
			_name(name), _size(size)
		{
			glGenFramebuffersEXT(1, &_glName);
		}
	
		/**
		 * Return the debug name.
		 */
		std::string getName() const { return _name; }

		/**
		 * Return the ith attached Texture.
		 */
		TexturePtr getTexture(unsigned int i) const
		{ 
			assert(i < _textures.size());
			return _textures[i];
		}

		/**
		 * Attach a Texture to this RenderTarget.
		 * Will verify completeness.
		 */
		void attachTexture(const TexturePtr& t);

		/**
		 * Attach a RenderBuffer to this RenderTarget.
		 */
		void attachRenderbuffer(const RenderbufferPtr& t);


		/**
		 * Bind the RenderTarget and save the current
		 * draw buffer.
		 */
		void bind();

		/**
		 * Unbind the RenderTarget and restore the saved
		 * draw buffer.
		 */
		void unbind();

		/**
		 * Destructor.
		 */
		RenderTarget() 
		{
		}
		
	private:
		/**
		 * Return true if the underlying framebuffer object is complete.
		 * Must be bound before calling...
		 */
		bool checkFBO();


		std::string _name;
		Vec2s _size;
		GLuint _glName;
		std::vector<TexturePtr> _textures;
		std::vector<RenderbufferPtr> _renderbuffers;
		GLint _savedDrawBuffer;


		static GLenum _buffers[];
};

typedef boost::shared_ptr<RenderTarget> RenderTargetPtr;

#endif

